cmake_minimum_required(VERSION 3.0)

project(hope LANGUAGES Fortran)

if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
  set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -ffree-line-length-none -ffpe-trap=invalid,zero,overflow")
  if (CMAKE_BUILD_TYPE STREQUAL "DEBUG")
    #set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -O0 -fcheck=all -g -fbacktrace")
    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -O0 -g -fcheck=all -fbacktrace -lgomp -fopenmp")
    #set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -O0 -g -fcheck=all -fbacktrace")
  else ()
    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Ofast -lgomp -fopenmp -fdefault-real-8")
  endif ()
elseif (CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
  if (CMAKE_BUILD_TYPE STREQUAL "DEBUG")
    #set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -no-wrap-margin -r8 -g -traceback -qopenmp -check bounds -check format -check uninit -check output_conversion -check arg_temp_created -check all")
    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -no-wrap-margin -r8 -g -traceback -qopenmp -check bounds -check format -check uninit -check output_conversion")
    #set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -no-wrap-margin -r8 -g -traceback -check bounds -check format -check uninit -check output_conversion")
  else ()
    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -no-wrap-margin -r8 -O3 -parallel -qopt-matmul -qmkl:parallel -qopenmp")
  endif ()
endif ()

if (DEFINED ENV{NETCDF} AND (NOT DEFINED ENV{NETCDF_ROOT}))
  set(ENV{NETCDF_ROOT} $ENV{NETCDF})
endif ()
if (DEFINED ENV{NETCDF_ROOT})
  message(STATUS "Use netCDF in $ENV{NETCDF_ROOT}.")
  include_directories("$ENV{NETCDF_ROOT}/include")
  link_directories("$ENV{NETCDF_ROOT}/lib")
else ()
  find_package(PkgConfig)
  if (PKG_CONFIG_FOUND)
    pkg_search_module(NETCDF REQUIRED netcdf)
    if (NETCDF_FOUND)
      include_directories(${NETCDF_INCLUDEDIR})
      link_directories(${NETCDF_LIBDIR})
    else ()
      message(FATAL_ERROR "Pkg-config could not find netcdf library!")
    endif ()
  else ()
    message(FATAL_ERROR "Unable to find pkg-config library!")
  endif ()
endif ()
list(APPEND EXTERNAL_LIBS netcdff)

if (DEFINED ENV{GPTL} AND (NOT DEFINED ENV{GPTL_ROOT}))
  set(ENV{GPTL_ROOT} $ENV{GPTL})
endif ()
if (DEFINED ENV{GPTL_ROOT})
  message(STATUS "Use GPTL in $ENV{GPTL_ROOT}.")
  include_directories("$ENV{GPTL_ROOT}/include")
  link_directories("$ENV{GPTL_ROOT}/lib")
else ()
  message(FATAL_ERROR "Unable to find GPTL in env variable!")
endif ()
list(APPEND EXTERNAL_LIBS gptl)

if (DEFINED ENV{LAPACK_ROOT})
  include_directories("$ENV{LAPACK_ROOT}")
  link_directories("$ENV{LAPACK_ROOT}")
  set(LAPACK_LINKER_FLAGS "-llapack")
else ()
  find_package(LAPACK)
  if (NOT LAPACK_FOUND)
    message(DEBUG "Unable to find LAPACK library, use internal routines.")
    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DNOLAPACK")
  endif ()
endif ()

add_subdirectory(lib/datetime)
add_subdirectory(lib/container)
add_subdirectory(lib/string)
add_subdirectory(lib/flogger)
add_subdirectory(lib/fiona)
add_subdirectory(lib/spark)
add_subdirectory(lib/recon)
add_subdirectory(lib/test)

set(utils
  src/utils/gptl_timer_mod.F90
  src/utils/math_mod.F90
  src/utils/time_mod.F90
  src/utils/phy_operator_mod.F90
)
add_library(utils ${utils})
target_link_libraries(utils spark fortran_datetime fortran_string fortran_container flogger ${LAPACK_LIBRARIES})

set(share
  src/share/params_mod.F90
  src/share/state_mod.F90
  src/share/static_mod.F90
  src/share/diag_mod.F90
  src/share/tend_mod.F90
  src/share/vertical_coord_mod.F90
  src/share/history_mod.F90
  src/share/ghost_interp_mod.F90
  src/share/hope_recon_mod.F90
)
add_library(share ${share})
target_link_libraries(share utils recon)

set(preproc
  src/preproc/hps_mod.F90
  src/preproc/met_preproc_mod.F90
  src/preproc/test_mod.F90
  src/preproc/topo_mod.F90
)
add_library(preproc ${preproc})
target_link_libraries(preproc share recon dycore_test)

set(dynamics
  src/dynamics/riemann_mod.F90
  src/dynamics/operators_adv_mod.F90
  src/dynamics/operators_sw_mod.F90
  src/dynamics/operators_nh_mod.F90
  src/dynamics/jab_mod.F90
  src/dynamics/dycore_mod.F90
  src/dynamics/time_schemes_mod.F90
  src/dynamics/hope_mod.F90
)
add_library(dynamics ${dynamics})
target_link_libraries(dynamics share preproc fortran_datetime recon ${LAPACK_LIBRARIES})

add_executable(hps.exe src/drivers/hps.F90)
target_link_libraries(hps.exe preproc netcdf netcdff gptl)

add_executable(hope.exe src/drivers/hope.F90)
target_link_libraries(hope.exe dynamics netcdf netcdff gptl)
